using UnityEngine;
using DG.Tweening;
using System;

/// <summary>
/// 抛物线移动策略
/// </summary>
public class ParabolicMovement : IMovementStrategy
{
    /// <summary>
    /// 抛物线高度系数
    /// </summary>
    private readonly float m_HeightFactor; 

    public ParabolicMovement(float heightFactor = 0.5f)
    {
        m_HeightFactor = Mathf.Clamp(heightFactor, 0.1f, 2f);
    }

    public void Move(GameObject bullet, Vector3 start, Vector3 end, float duration, Action callback)
    {
        // 计算中间控制点（抛物线顶点）
        Vector3 controlPoint = CalculateControlPoint(start, end);

        // 使用路径动画实现抛物线
        bullet.transform.DOPath(
            new[] { start, controlPoint, end },
            duration,
            PathType.CatmullRom,  // 使用Catmull-Rom插值获得更平滑的曲线
            PathMode.Full3D       // 支持3D空间
        )
        .SetEase(Ease.Linear)     // 线性运动
        .OnComplete(() => callback?.Invoke());
    }

    private Vector3 CalculateControlPoint(Vector3 start, Vector3 end)
    {
        // 计算水平中点
        Vector3 midpoint = (start + end) * 0.5f;

        // 计算起点到终点的距离
        float distance = Vector3.Distance(start, end);

        // 计算垂直方向
        Vector3 upDirection = GetUpDirection(start, end);

        // 计算抛物线高度（基于距离的比例）
        return midpoint + upDirection * (distance * m_HeightFactor);
    }

    private Vector3 GetUpDirection(Vector3 start, Vector3 end)
    {
        // 计算前进方向
        Vector3 direction = (end - start).normalized;

        // 如果前进方向接近垂直，使用水平方向作为上方向
        if (Mathf.Abs(Vector3.Dot(direction, Vector3.up)) > 0.9f)
        {
            return Vector3.Cross(direction, Vector3.right).normalized;
        }

        // 否则使用世界坐标系的上方向
        return Vector3.up;
    }
}